using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Security.AccessControl;

namespace FileServerDocumenter.Library
{
    public class Util
    {
        public static void DirectoryInfoToFile(List<System.IO.DirectoryInfo> myList, 
            String outputFilePath, String securityOutputFilePath,
            bool IncludeDirectorySize, bool IncludeFileCount, bool IncludedDirectorySecurity)
        { 
            StreamWriter sw = new StreamWriter(outputFilePath);
            String template = "ShareName, NumberOfFiles, DirectorySize, Comment, CreationTime, LastAccessTime";
            sw.WriteLine(template);

            StreamWriter swSecurity = null;
            if (securityOutputFilePath != "")
            {
                swSecurity = new StreamWriter(securityOutputFilePath);
                swSecurity.WriteLine("ShareName, RuleType, IdentityReference, AccessControlType, FileSystemRights, InheritanceFlags, IsInherited, PropagationFlags");            
            }

            String line;

            foreach (DirectoryInfo di in myList)
            {
                Console.WriteLine ("Examining " + di.FullName);

                line = template;
   
                line = line.Replace("ShareName", di.FullName);

                try
                {
                    line = line.Replace("CreationTime", di.CreationTime.ToString());
                }
                catch
                {
                    line = line.Replace("CreationTime", "");
                }

                try
                {
                    line = line.Replace("LastAccessTime", di.LastAccessTime.ToString());
                }
                catch
                {
                    line = line.Replace("LastAccessTime", "");
                }
                
                line = line.Replace("NumberOfFiles", "");
                if (IncludeDirectorySize)
                {
                    line = line.Replace("DirectorySize", getDirectorySize(di).ToString());
                }
                else
                {
                    line = line.Replace("DirectorySize", "");
                }
                //
                line = line.Replace("Comment", "");

                if (swSecurity != null)
                {
                    //acl stuff
                    try
                    {
                        System.Security.AccessControl.DirectorySecurity ds = di.GetAccessControl();
                        DisplayDirSecurityInfo(ds, swSecurity, di.FullName);
                    }
                    catch (UnauthorizedAccessException ex)
                    { }
                }                

                sw.WriteLine(line);
            }
            
            sw.Close();
            if (swSecurity != null)
            {
                swSecurity.Close();
            }

        }

        private static long getDirectorySize(DirectoryInfo myDirectory)
        {
            long size = 0;

            try
            {
                foreach (FileInfo fi in myDirectory.GetFiles())
                {
                    Console.WriteLine(fi.Name);
                    size += fi.Length;
                }

                foreach (DirectoryInfo di in myDirectory.GetDirectories())
                {
                    Console.WriteLine(di.Name);
                    size += getDirectorySize(di);
                }
            }
            catch
            { }

            return size;
        }

        public static void DisplayDirSecurityInfo(DirectorySecurity dirSec, StreamWriter sw, String DirectoryName)
        {
            sw.WriteLine("{0}, {1}, {2}", 
                DirectoryName, "SecurityDescriptor", dirSec.GetSecurityDescriptorSddlForm(AccessControlSections.All));

            foreach (FileSystemAccessRule ace in
                    dirSec.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount)))
            {
                sw.WriteLine("{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}",
                        DirectoryName,
                        "FileSystemAccessRule",
                        ace.IdentityReference.Value,
                        ace.AccessControlType,
                        ace.FileSystemRights,
                        ace.InheritanceFlags,
                        ace.IsInherited,
                        ace.PropagationFlags);
            }

            foreach (FileSystemAuditRule ace in
                    dirSec.GetAuditRules(true, true, typeof(System.Security.Principal.NTAccount)))
            {
                sw.WriteLine("{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}",
                    DirectoryName,
                    "FileSystemAuditRule",
                    ace.IdentityReference.Value,
                    ace.AuditFlags,
                    ace.FileSystemRights,
                    ace.InheritanceFlags,
                    ace.IsInherited,
                    ace.PropagationFlags);
            }

            sw.WriteLine("{0}, {1}, {2}",
                DirectoryName, "Group", dirSec.GetGroup(typeof(System.Security.Principal.NTAccount)).Value);

            try
            {
                sw.WriteLine("{0}, {1}, {2}",
                    DirectoryName, "Owner", dirSec.GetOwner(typeof(System.Security.Principal.NTAccount)).Value);
            }
            catch (System.Security.Principal.IdentityNotMappedException) { }
        }
    }
}
